package com.pi.shisan.util;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.text.NumberFormat;

@Slf4j
public class FileUtils {

	/**
	 * 转换文件大小格式
	 * @param b
	 * @return
	 */
	public static String formatB(long b) {

		if (b >= 1073741824L) { // GB等级

			return formatDoubleNum(b / 1024 / 1024 / 1024D) + "GB";

		} else if (b >= 1048576) { // MB级别

			return formatDoubleNum(b / 1024 / 1024D) + "MB";

		} else if (b >= 1024) { // KB级别

			return formatDoubleNum(b / 1024D) + "KB";

		} else {

			return (int) b + "Byte";

		}

	}

	/**
	 * 保留两位小数 向下取
	 * @param num
	 * @return
	 */
	public static String formatDoubleNum(double num) {

		DecimalFormat df = (DecimalFormat)NumberFormat.getInstance();
		df.setGroupingUsed(false);
		df.setMaximumFractionDigits(2);
		df.setRoundingMode(RoundingMode.HALF_UP);
		return df.format(num);

	}

	/**
	 * 获取文件名称，去掉扩展名
	 * @param name
	 * @return
	 */
	public static String getFileNameSuffix(String name) {
		int index;
		if ((index = name.lastIndexOf(".")) > -1) {
			return name.substring(index + 1, name.length());
		}
		return null;
	}
	
	/**
	 * 获取文件扩展名
	 * @param name
	 * @return
	 */
	public static String getFileNameWithoutSuffix(String name) {
		int index;
		if ((index = name.lastIndexOf(".")) > -1) {
			return name.substring(0,index);
		}
		return null;
	}

	public static void delteAllFiles(File file){
		if(file.isFile()) file.delete();
		else{
			File files[] = file.listFiles();
			if(files != null){
				for(File f:files) delteAllFiles(f);
			}
			file.delete();
		}

	}

	public static void tryToFocusDeleteFile(File file) {
		if (file == null || !file.exists()) {
			return;
		}
		int retire = 10;
		do {
			if (retire < 10) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
				}
			}
			file.delete();
		} while (file.exists() && retire -- > 0);
		if (file.exists()) {
			log.error("文件删除失败：{}",file.getAbsolutePath());
		}
	}

	public static void tryToFocusDeleteFileAsync(File file) {
		//因为这里的操作并不频繁，没必要维护一个线程池，线程用完即释放即可
		new Thread(()->{
			tryToFocusDeleteFile(file);
		}).start();
	}
	
	/**
	 * 文件copy
	 * @param is
	 * @param os
	 * @throws Exception
	 */
	public static void copyFile(InputStream is,OutputStream os) throws Exception{
		int read=0;
		byte b[] = new byte[1024];
		try{
			while((read=is.read(b))>0){
				os.write(b,0,read);
			}
			os.flush();
		}catch (Exception e){
			e.printStackTrace();
		}finally {
			try{
				os.close();
			}catch (Exception e1){}
			try{
				is.close();
			}catch (Exception e1){}
		}
	}
	
	public static byte[] readFileToByteArray(File file) throws Exception{
		FileInputStream fis = null;
		ByteArrayOutputStream bos = null;
		try{
			fis = new FileInputStream(file);
			bos = new ByteArrayOutputStream();
			int read;
			byte b[] = new byte[1024];
			while((read=fis.read(b))>-1){
				bos.write(b,0,read);
			}
		}catch (Exception e){
			e.printStackTrace();
		}finally {
			try{
				fis.close();
			}catch (Exception e1){}
		}
		return bos.toByteArray();
	}

	public static void saveObject(Object obj,String path){
		FileOutputStream fos = null;
		ObjectOutputStream oos =null;
		try {
			fos = new FileOutputStream(path);
			oos = new ObjectOutputStream(fos);
			oos.writeObject(obj);
			oos.flush();
			fos.flush();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			try{
				oos.close();
			}catch (Exception e){}
			try{
				fos.close();
			}catch (Exception e){}
		}
	}
	public static Object readObject(String path){
		FileInputStream fis = null;
		ObjectInputStream ois =null;
		try {
			fis = new FileInputStream(path);
			ois = new ObjectInputStream(fis);
			return ois.readObject();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			try{
				ois.close();
			}catch (Exception e){}
			try{
				fis.close();
			}catch (Exception e){}
		}
	}

	public static void writeStringToFile(String path,String content,String charset){
		FileOutputStream fos = null;
		OutputStreamWriter osw = null;
		try{
			fos = new FileOutputStream(path);
			osw = new OutputStreamWriter(fos);
			osw.write(content);
			osw.flush();
			fos.flush();
		}catch (Exception e){
			e.printStackTrace();
		}finally {
			try{
				osw.close();
			}catch (Exception e2){}
			try{
				fos.close();
			}catch (Exception e2){}
		}
	}

	public static String readTextFromStream(InputStream is,String encoding){
		InputStreamReader isr = null;
		BufferedReader br = null;
		StringBuilder builder = new StringBuilder();
		try{
			isr = new InputStreamReader(is,encoding==null? Charset.defaultCharset().name():encoding);
			br = new BufferedReader(isr);
			String read;
			while((read=br.readLine())!=null){
				builder.append(read).append("\n");
			}
		}catch (Exception e){
			throw new RuntimeException(e);
		}finally {
			try {
				br.close();
			}catch (Exception e){}
			try {
				isr.close();
			}catch (Exception e){}
			try {
				is.close();
			}catch (Exception e){}
		}
		return builder.toString();
	}

	public static String readFileToString(String path,String charset){
		FileInputStream fis = null;
		InputStreamReader isr = null;
		BufferedReader reader = null;
		try{
			fis = new FileInputStream(path);
			isr = new InputStreamReader(fis,charset);
			reader = new BufferedReader(isr);
			StringBuilder builder = new StringBuilder();
			String text;
			while((text = reader.readLine())!=null){
				builder.append(text).append("\n");
			}
			return builder.toString();
		}catch (Exception e){
			e.printStackTrace();
		}finally {
			try{
				fis.close();
			}catch (Exception e2){}
			try{
				isr.close();
			}catch (Exception e2){}
			try{
				reader.close();
			}catch (Exception e2){}
		}
		return null;
	}
}
